home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / util / misc / HunkReader.lha / HunkReader / src / HunkReader.c < prev   
Encoding:
C/C++ Source or Header  |  1999-08-27  |  25.2 KB  |  1,032 lines

  1.  
  2. /*
  3.  * [!BGN - MACHINE GENERATED - DO NOT EDIT THIS HEADER]
  4.  *
  5.  * Program   : HunkReader (Executable/Object file hunk viewer)
  6.  * Version   : 1.4
  7.  * File      : Work:Source/!WIP/HunkReader/HR.c
  8.  * Author    : Andrew Bell
  9.  * Copyright : Copyright © 1999 Andrew Bell, All rights reserved.
  10.  * Created   : Saturday 15-Nov-97 08:30:00
  11.  * Modified  : Friday 27-Aug-99 01:06:09
  12.  * Comment   : 
  13.  *
  14.  * (Generated with StampSource 1.2 by Andrew Bell)
  15.  *
  16.  * [!END - MACHINE GENERATED - DO NOT EDIT THIS HEADER]
  17.  *
  18.  */
  19.  
  20. /* Created: Sat/15/Nov/1997 */
  21.  
  22. #define MONTH   "August"
  23. #define YEAR    "1997-99"
  24. #define EMAIL "andrew.ab2000@bigfoot.com"
  25. #define WWW "http://www.homeusers.prestel.co.uk/ab2000"
  26.  
  27. /* Maybe one day I'll make this code totally portable. */
  28.  
  29. /* Includes */
  30.  
  31. #include <HunkReader_rev.h>
  32.  
  33. #include <exec/types.h>
  34. #include <exec/execbase.h>
  35. #include <exec/memory.h>
  36.  
  37. #include <dos/dos.h>
  38. #include <dos/dosextens.h>
  39. #include <dos/doshunks.h>
  40. #include <dos/stdio.h>
  41.  
  42. #include <clib/exec_protos.h>
  43. #include <clib/dos_protos.h>
  44. #include <pragma/exec_lib.h>
  45. #include <pragma/dos_lib.h>
  46.  
  47. #pragma header
  48.  
  49. /* Defines */
  50.  
  51. #define MASK ( HUNKF_ADVISORY | HUNKF_CHIP | HUNKF_FAST )
  52.  
  53. #define TEMPLATE "FILE/A,DSYM/S,DREL/S,DEXT/S,STATS/S"
  54.  
  55. enum
  56. {
  57.   ARG_FILE = 0,     /* Incoming file */
  58.   ARG_DSYM,         /* Display symbol tables */
  59.   ARG_DREL,         /* Display reloc tables */
  60.   ARG_DEXT,         /* Display ext hunks */
  61.   ARG_STATS,        /* Display stats */
  62.   ARG_AMT           /* Array size */
  63. };
  64.  
  65. /* Prototypes */
  66.  
  67. void DoErr( void );
  68. void DumpHunks( BPTR );
  69. ULONG MoveForward( BPTR, LONG );
  70. BOOL TestAbort( void );
  71. void BuildFlagString( ULONG, UBYTE *);
  72. LONG MyRead( BPTR FH, APTR Buf, ULONG Length);
  73. UBYTE *Plural( ULONG, UBYTE *, UBYTE *);
  74.  
  75. void DoHUNK_EXT( BPTR FH );
  76. void DoUNKNOWN( BPTR FH );
  77. void DoHUNK_HEADER( BPTR FH );
  78. void DoHUNK_CODE( BPTR FH );
  79. void DoHUNK_DATA( BPTR FH );
  80. void DoHUNK_BSS( BPTR FH );
  81. void DoHUNK_END( BPTR FH );
  82. void DoHUNK_OVERLAY( BPTR FH);
  83. void DoHUNK_BREAK( BPTR FH );
  84. void DoHUNK_DEBUG( BPTR FH );
  85. void DoHUNK_SYMBOL( BPTR FH );
  86. void DoHUNK_RELOC32( BPTR FH );
  87. void DoHUNK_DREL32( BPTR FH );
  88. void DoHUNK_RELOC32SHORT( BPTR FH );
  89. void DoHUNK_DREL32( BPTR FH );
  90. void DoHUNK_UNIT( BPTR FH );
  91. void DoHUNK_NAME( BPTR FH );
  92. void DoHUNK_EXT( BPTR FH );
  93.  
  94. /* We let the startup code/linker deal with these */
  95.  
  96. extern struct ExecBase *SysBase;
  97. extern struct Library *DOSBase;
  98.  
  99.  
  100. /* Varables and data */
  101.  
  102. static UBYTE VerTag[] = VERSTAG;
  103.  
  104. ULONG aa[ARG_AMT];
  105. ULONG stream[99];
  106. UBYTE TempBuffer[256+4];
  107.  
  108. /***********************************************************************/
  109.  
  110. ULONG main( void )
  111. {
  112.   struct RDArgs *ArgInfo;
  113.  
  114.   if (SysBase->LibNode.lib_Version < 37)
  115.   {
  116.     #define BADOSTXT "Sorry, this program requires at least OS 37+\n"
  117.     
  118.     Write(Output(), BADOSTXT, sizeof(BADOSTXT) );
  119.     return RETURN_FAIL;
  120.   }
  121.   
  122.   if (!(SysBase->AttnFlags & AFF_68020))
  123.   {
  124.     #define BADCPUTXT "Sorry, this program requires at least a MC68020\n"
  125.  
  126.     Write(Output(), BADOSTXT, sizeof(BADOSTXT) );
  127.     return RETURN_FAIL;   
  128.   }
  129.   
  130.   if (ArgInfo = (struct RDArgs *) ReadArgs(TEMPLATE, (LONG *) &aa, NULL))
  131.   {
  132.     BPTR InLock;
  133.  
  134.     Printf(VERS " (" DATE "),\n"
  135.           "Copyright © " YEAR " Andrew Bell, All rights reserved.\n"
  136.           "email: " EMAIL "\n"
  137.           "  web: " WWW "\n");
  138.  
  139.     if (InLock = Lock( (UBYTE *) aa[ARG_FILE], SHARED_LOCK))
  140.     {
  141.       struct FileInfoBlock *FIB;
  142.  
  143.       if (FIB = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, NULL))
  144.       {
  145.         if (Examine(InLock, FIB))
  146.         {
  147.           if (FIB->fib_DirEntryType < 0)
  148.           {
  149.             if (FIB->fib_Size)
  150.             {
  151.               BPTR InHandle;
  152.  
  153.               Printf("\nViewing %s's hunks structure, length %lu bytes.\n\n",
  154.                 &FIB->fib_FileName, FIB->fib_Size);
  155.  
  156.               if (InHandle = Open( (UBYTE *) aa[ARG_FILE], MODE_OLDFILE))
  157.               {
  158.                 if (SysBase->LibNode.lib_Version >= 40)
  159.                 {
  160.                   SetVBuf(InHandle, NULL, BUF_FULL, (64*1024));
  161.                 }
  162.                                 
  163.                 DumpHunks(InHandle);
  164.                 Close(InHandle);
  165.  
  166.               }   /* Open */
  167.               else DoErr();
  168.  
  169.             }   /* NULL length check */
  170.             else Printf("Subject file is empty!\n");
  171.  
  172.           }   /* File/dir check */
  173.           else Printf("I need a file, not a directory!\n");
  174.  
  175.         }   /* Examine() */
  176.         else DoErr();
  177.  
  178.         FreeDosObject(DOS_FIB, FIB);
  179.  
  180.       } /* AllocDosObject() */
  181.       else DoErr();
  182.  
  183.       UnLock(InLock);
  184.  
  185.     } /* Lock() */
  186.     else DoErr();
  187.  
  188.     FreeArgs(ArgInfo);
  189.  
  190.   } /* ReadArgs() */
  191.   else DoErr();
  192.  
  193.   return RETURN_OK;
  194.  
  195. } /* _main() */
  196.  
  197. /***********************************************************************/
  198.  
  199. void DoErr( void )
  200. {
  201.   PrintFault(IoErr(), "Error ");
  202. }
  203.  
  204. /***********************************************************************/
  205.  
  206. /* Global variables */
  207.  
  208. BOOL Flag_EOF    = FALSE; /* Will equal TRUE if EOF (All OK) */
  209. BOOL Flag_UEOF   = FALSE; /* Will equal TRUE if unexpected EOF  */
  210. BOOL Flag_Error  = FALSE; /* Will equal TRUE if error happened */
  211. BOOL Flag_BadId  = FALSE; /* Unknown hunk pop up it's ugly head */
  212. BOOL Flag_Break  = FALSE; /* Will equal TRUE if Ctrl+C is hit */
  213. BOOL Flag_NotSup = FALSE; /* Hunk type is not supported */
  214.  
  215. BOOL FFlag_Exe   = FALSE; /* Will equal TRUE if HUNK_HEADER was encontered */
  216. BOOL FFlag_Obj   = FALSE; /* Will equal TRUE if HUNK_UNIT was encontered */
  217.  
  218. ULONG HunkOrgId  = NULL;  /* Unaltered ID, contains length + bits */
  219. ULONG HunkId     = NULL;  /* Altered ID, contains length only */
  220. ULONG HunkFlags  = NULL;  /* Altered ID, contains bits only */
  221. ULONG HunkOffset = NULL;
  222. ULONG HunkCnt    = NULL;
  223.  
  224. /* Zero all of these */
  225.  
  226. ULONG Cnt_Header       = 0; /* */
  227. ULONG Cnt_Code         = 0; /* */
  228. ULONG Cnt_Data         = 0; /* */
  229. ULONG Cnt_BSS          = 0; /* */
  230. ULONG Cnt_End          = 0; /* */
  231. ULONG Cnt_Overlay      = 0; /* */
  232. ULONG Cnt_Break        = 0; /* */
  233. ULONG Cnt_Symbol       = 0; /* */
  234. ULONG Cnt_SymbolEnt    = 0; /* */
  235. ULONG Cnt_Debug        = 0; /* */
  236. ULONG Cnt_Reloc32      = 0; /* */
  237. ULONG Cnt_Reloc32Ent   = 0; /* Number of entries */
  238. ULONG Cnt_Reloc32Short = 0; /* */
  239. ULONG Cnt_Reloc32SEnt  = 0; /* Number of entries */
  240. ULONG Cnt_DRel32       = 0; /* */
  241. ULONG Cnt_DRel32Ent    = 0; /* */
  242.  
  243. ULONG Cnt_HunksChip    = 0; /* */
  244. ULONG Cnt_HunksFast    = 0; /* */
  245. ULONG Cnt_HunksPub     = 0; /* */
  246. ULONG Cnt_HunksAdv     = 0; /* */
  247.  
  248. ULONG TOTALAlloc = 0;
  249.  
  250. void DumpHunks( BPTR FH )
  251. {
  252.   LONG ReadResult;
  253.  
  254.   do
  255.   {
  256.     HunkOffset = Seek(FH, 0, OFFSET_CURRENT);
  257.  
  258.     if (HunkOffset == -1)
  259.     {
  260.       Flag_Error = TRUE; break;
  261.     }
  262.  
  263.     if ((ReadResult = Read(FH, &HunkOrgId, 4)) == -1)
  264.     {
  265.       Flag_Error = TRUE; break;
  266.     }
  267.  
  268.     if (ReadResult == NULL)
  269.     {
  270.       Flag_EOF=TRUE; break;
  271.     }
  272.  
  273.     HunkId = HunkOrgId;
  274.  
  275.     HunkFlags = HunkId & MASK;  /* extract flag bits from id */
  276.     HunkId &= ~MASK;        /* remove flag bits from id */
  277.  
  278.     switch(HunkId)
  279.     {
  280.       case HUNK_HEADER: DoHUNK_HEADER(FH); break;
  281.       case HUNK_CODE: DoHUNK_CODE(FH); break;
  282.       case HUNK_DATA: DoHUNK_DATA(FH); break;
  283.       case HUNK_BSS: DoHUNK_BSS(FH); break;
  284.       case HUNK_END: DoHUNK_END(FH); break;
  285.       case HUNK_RELOC32: DoHUNK_RELOC32(FH); break;
  286.       case HUNK_RELOC32SHORT: DoHUNK_RELOC32SHORT(FH); break;
  287.       case HUNK_DREL32: DoHUNK_DREL32(FH); break;
  288.  
  289.       case HUNK_OVERLAY: DoHUNK_OVERLAY(FH); break;
  290.       case HUNK_BREAK: DoHUNK_BREAK(FH); break;
  291.       case HUNK_DEBUG: DoHUNK_DEBUG(FH); break;
  292.       case HUNK_SYMBOL: DoHUNK_SYMBOL(FH); break;
  293.  
  294.       case HUNK_UNIT: DoHUNK_UNIT(FH); break;
  295.       case HUNK_NAME: DoHUNK_NAME(FH); break;
  296.       case HUNK_EXT: DoHUNK_EXT(FH); break;
  297.  
  298.       default: DoUNKNOWN(FH); break;
  299.     }
  300.  
  301.   TestAbort();
  302.  
  303.   }
  304.   while(    (Flag_EOF == FALSE)
  305.       &&  (Flag_UEOF == FALSE)
  306.       &&  (Flag_Error == FALSE)
  307.       &&  (Flag_BadId == FALSE)
  308.       &&  (Flag_Break == FALSE)
  309.       &&  (Flag_NotSup == FALSE) );
  310.  
  311.   Printf("\n");
  312.  
  313.   if (Flag_EOF)
  314.   {
  315.     Printf("\t\tEnd of file\n\n");
  316.  
  317.     if (aa[ARG_STATS])
  318.     {
  319.       /* This test does not show all hunks! */
  320.  
  321.       Printf("    Object Type: %s\n"
  322.           "      Amt Hunks: %lu\n"
  323.           "    Hunk_Header: %lu\n"
  324.           "      Hunk_Code: %lu\n"
  325.           "      Hunk_Data: %lu\n"
  326.           "       Hunk_BSS: %lu\n"
  327.           "       Hunk_End: %lu\n"
  328.           "   Hunk_Overlay: %lu\n"
  329.           "     Hunk_Break: %lu\n"
  330.           "    Hunk_Symbol: %lu (total entries: %lu)\n"
  331.           "     Hunk_Debug: %lu\n"
  332.           "   Hunk_Reloc32: %lu (total entries: %lu, %lu bytes)\n"
  333.           " Hunk_Reloc32Sh: %lu (total entries: %lu, %lu bytes)\n"
  334.           "    Hunk_DRel32: %lu (total entries: %lu, %lu bytes)\n"
  335.  
  336.           "   Hunks > Chip: %lu\n"
  337.           "   Hunks > Fast: %lu\n"
  338.           " Hunks > Public: %lu\n"
  339.           " Advisory Hunks: %lu\n"
  340.           "\n"
  341.           " Amount of memory required to load program, approx: %lu (exe only)\n"
  342.           "\n",
  343.         
  344.       (ULONG) (FFlag_Exe ? "Command file" : "Linkable object file"),
  345.       HunkCnt,
  346.  
  347.       Cnt_Header,
  348.       Cnt_Code,
  349.       Cnt_Data,
  350.       Cnt_BSS,
  351.       Cnt_End,
  352.       Cnt_Overlay,
  353.       Cnt_Break,
  354.       Cnt_Symbol,
  355.       Cnt_SymbolEnt,
  356.       Cnt_Debug,
  357.  
  358.       Cnt_Reloc32,
  359.       Cnt_Reloc32Ent,
  360.       Cnt_Reloc32Ent << 2,
  361.  
  362.       Cnt_Reloc32Short,
  363.       Cnt_Reloc32SEnt,
  364.       Cnt_Reloc32SEnt << 2, /* Use real bytes here */
  365.  
  366.       Cnt_DRel32,
  367.       Cnt_DRel32Ent,
  368.       Cnt_DRel32Ent << 2,
  369.  
  370.       Cnt_HunksChip,
  371.       Cnt_HunksFast,
  372.       Cnt_HunksPub,
  373.       Cnt_HunksAdv,
  374.       TOTALAlloc );
  375.     }
  376.  
  377.   }
  378.   else if (Flag_UEOF)
  379.     Printf("\t\tUnexpected end of file, bad file structure!\n\n");
  380.   else if (Flag_Error)
  381.     DoErr();
  382.   else if (Flag_BadId)
  383.     Printf("\t\tEncountered an unknown hunk type!\n");
  384.   else if (Flag_NotSup)
  385.     Printf("\t\tEncountered an unsupported hunk type!\n");
  386. }
  387.  
  388. /***********************************************************************/
  389.  
  390. void DoHUNK_HEADER( BPTR FH )
  391. {
  392.   ULONG HunkATInfo[4];    /* Hunk Allocation Table Info */
  393.   ULONG HunkASize;
  394.   ULONG HunkCnt;
  395.   ULONG HunkRange;
  396.   ULONG AllocFlags;
  397.  
  398.   Cnt_Header++;
  399.  
  400.   FFlag_Exe = TRUE;
  401.  
  402.   Printf("\n\tOffset: 0x%08lx - 0x%08lx - HUNK_HEADER\n",
  403.     HunkOffset, HunkOrgId);
  404.  
  405.   if (MyRead(FH, &HunkATInfo, 4*4)) return; /* Read 4 LONGs */
  406.  
  407.   Printf("\t\tAmt of hunks in alloc table: %lu (%lu to %lu)\n",
  408.     HunkATInfo[1], /* Amt  */
  409.     HunkATInfo[2], /* Rng1 */
  410.     HunkATInfo[3]  /* Rng2 */ );
  411.  
  412.   HunkRange=(HunkATInfo[3]-HunkATInfo[2])+1; /* (Rng2-Rng1) + 1 */
  413.  
  414.   for (HunkCnt = 0; HunkCnt < HunkRange ; HunkCnt++)
  415.   {
  416.     if (MyRead(FH, &HunkASize, 4)) return;
  417.  
  418.     AllocFlags = HunkASize & MASK;    /* Keep alloc flags */
  419.  
  420.     BuildFlagString(HunkASize, TempBuffer);
  421.  
  422.     if (AllocFlags & HUNKF_ADVISORY) Cnt_HunksAdv++;
  423.     else if (AllocFlags & HUNKF_FAST) Cnt_HunksFast++;
  424.     else if (AllocFlags & HUNKF_CHIP) Cnt_HunksChip++;
  425.     else Cnt_HunksPub++;
  426.  
  427.     HunkASize &= ~MASK; /* remove flags */
  428.  
  429.     TOTALAlloc += (HunkASize << 2);
  430.  
  431.     Printf("\t\tHunk %3lu, length %9lu %s\n",
  432.       HunkCnt, HunkASize * 4, &TempBuffer );
  433.  
  434.     if (TestAbort()) return;
  435.   }
  436. }
  437.  
  438. /***********************************************************************/
  439.  
  440. void DoHUNK_CODE( BPTR FH )
  441. {
  442.   ULONG HunkLength;
  443.  
  444.   Cnt_Code++;
  445.  
  446.   Printf("Hnk #%lu\tOffset: 0x%08lx - 0x%08lx - HUNK_CODE\n",
  447.     HunkCnt++, HunkOffset, HunkOrgId );
  448.  
  449.   if (MyRead(FH, &HunkLength, 4)) return;
  450.   
  451.   HunkLength *= 4;
  452.  
  453.   BuildFlagString(HunkOrgId, TempBuffer);
  454.  
  455.   Printf("\t\tRead length - %lu %s\n",
  456.     HunkLength, (ULONG)TempBuffer );
  457.  
  458.   if (MoveForward(FH, HunkLength)) return;
  459. }
  460.  
  461. /***********************************************************************/
  462.  
  463. void DoHUNK_DATA( BPTR FH )
  464. {
  465.   ULONG HunkLength;
  466.  
  467.   Cnt_Data++;
  468.  
  469.   Printf("Hnk #%lu\tOffset: 0x%08lx - 0x%08lx - HUNK_DATA\n",
  470.     HunkCnt++, HunkOffset, HunkOrgId, &stream);
  471.  
  472.   if (MyRead(FH, &HunkLength, 4)) return; HunkLength *= 4;
  473.  
  474.   BuildFlagString(HunkOrgId, TempBuffer);
  475.  
  476.   Printf("\t\tRead length - %lu %s\n",
  477.     HunkLength, TempBuffer );
  478.  
  479.   if (MoveForward(FH, HunkLength)) return;
  480. }
  481.  
  482. /***********************************************************************/
  483.  
  484. void DoHUNK_BSS( BPTR FH )
  485. {
  486.   ULONG HunkLength;
  487.  
  488.   Cnt_BSS++;
  489.  
  490.   Printf("Hnk #%lu\tOffset: 0x%08lx - 0x%08lx - HUNK_BSS\n",
  491.     HunkCnt++, HunkOffset, HunkOrgId );
  492.  
  493.   if (MyRead(FH, &HunkLength, 4)) return; HunkLength*=4;
  494.  
  495.   BuildFlagString(HunkOrgId, TempBuffer);
  496.  
  497.   Printf("\t\tAllocation length - %lu %s\n",
  498.     HunkLength, TempBuffer );
  499. }
  500.  
  501. /***********************************************************************/
  502.  
  503. void DoHUNK_END( BPTR FH )
  504. {
  505.   Cnt_End++;
  506.  
  507.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_END\n",
  508.     HunkOffset, HunkOrgId );
  509. }
  510.  
  511. /***********************************************************************/
  512.  
  513. void DoHUNK_OVERLAY( BPTR FH )
  514. {
  515.   ULONG HunkLength;
  516.  
  517.   Cnt_Overlay++;
  518.  
  519.   Printf("Hnk #%lu\tOffset: 0x%08lx - 0x%08lx - HUNK_OVERLAY\n",
  520.     HunkCnt++, HunkOffset, HunkOrgId );
  521.  
  522.   if (MyRead(FH, &HunkLength, 4)) return; HunkLength*=4;
  523.  
  524.   BuildFlagString(HunkOrgId, TempBuffer);
  525.  
  526.   Printf("\t\tLength - %lu %s\n",
  527.     HunkLength, TempBuffer );
  528.  
  529.   if (MoveForward(FH, HunkLength+4)) return;
  530. }
  531.  
  532. /***********************************************************************/
  533.  
  534. void DoHUNK_BREAK( BPTR FH )
  535. {
  536.   Cnt_Break++;
  537.  
  538.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_BREAK\n",
  539.     HunkOffset, HunkOrgId );
  540. }
  541.  
  542. /***********************************************************************/
  543.  
  544. void DoHUNK_DEBUG( BPTR FH )
  545. {
  546.   ULONG HunkLength;
  547.  
  548.   Cnt_Debug++;
  549.  
  550.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_DEBUG\n",
  551.     HunkOffset, HunkOrgId, &stream);
  552.  
  553.   if (MyRead(FH, &HunkLength, 4)) return; HunkLength *= 4;
  554.  
  555.   BuildFlagString(HunkOrgId, TempBuffer);
  556.  
  557.   Printf("\t\tLength - %lu\n", HunkLength, TempBuffer );
  558.  
  559.   if (MoveForward(FH, HunkLength)) return;
  560. }
  561.  
  562. /***********************************************************************/
  563. /* Length, <........>, Offset */
  564.  
  565. /* TODO: Merge this hunk with HUNK_EXT, because both are identical */
  566.  
  567. void DoHUNK_SYMBOL( BPTR FH )
  568. {
  569.   APTR SymBuf;
  570.   ULONG SymCnt,SymLen,SymOffset;
  571.   ULONG R1,R2;
  572.  
  573.   Cnt_Symbol++;
  574.  
  575.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_SYMBOL\n",
  576.     HunkOffset, HunkOrgId );
  577.  
  578.   for(SymCnt = 0;;)
  579.   {
  580.     if (MyRead(FH, &SymLen, 4)) return;
  581.     if (SymLen == NULL) break;
  582.  
  583.     if (aa[ARG_DSYM])
  584.     {
  585.       if (SymBuf = (APTR)AllocVec( (SymLen + 1) * 4, MEMF_CLEAR))
  586.       {
  587.         R1 = MyRead(FH, SymBuf, SymLen*4);      /* Read symbol */
  588.         R2 = MyRead(FH, &SymOffset, 4);       /* Read offset */
  589.  
  590.         Printf( "\t\t[%-30.30s] at 0x%08lx (%lu)\n",
  591.           SymBuf, SymOffset, SymOffset );
  592.  
  593.         FreeVec(SymBuf);
  594.  
  595.         if (R1 || R2) return;
  596.       }
  597.       else
  598.         if (MoveForward(FH, (SymLen+1)*4)) return;  /* Skip symbol + offset */
  599.     }
  600.     else
  601.       if (MoveForward(FH, (SymLen+1)*4)) return;  /* Skip symbol + offset */
  602.  
  603.     if (TestAbort()) return;
  604.  
  605.     SymCnt++;
  606.   }
  607.  
  608.   Printf("\t\tContains %lu symbol entr%s\n",
  609.     SymCnt, Plural( SymCnt, "y", "ies" ));
  610.  
  611.   Cnt_SymbolEnt += SymCnt;
  612. }
  613.  
  614. /***********************************************************************/
  615. /* Amount, Hunk, <........> */
  616.  
  617. void DoHUNK_RELOC32( BPTR FH )
  618. {
  619.   ULONG RelocAmt,RelocHunk;
  620.   Cnt_Reloc32++;
  621.  
  622.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_RELOC32\n",
  623.     HunkOffset, HunkOrgId );
  624.  
  625.   for(;;)
  626.   {
  627.     if (MyRead(FH, &RelocAmt, 4)) return;
  628.     if (RelocAmt == NULL) break;          /* End of table? */
  629.     if (MyRead(FH, &RelocHunk, 4)) return;
  630.  
  631.     Cnt_Reloc32Ent+=RelocAmt;
  632.  
  633.     Printf("\t\t%lu reference%s to hunk #%lu\n",
  634.           RelocAmt, Plural(RelocAmt, "", "s"), RelocHunk );
  635.  
  636.     if (aa[ARG_DREL])
  637.     {
  638.       while (RelocAmt--)
  639.       {
  640.         ULONG Rel32;
  641.         
  642.         if (MyRead(FH, &Rel32, 4)) return;
  643.  
  644.         Printf("\t\tRelocate offset 0x%08lx using hunk base #%lu\n",
  645.           Rel32, RelocHunk );
  646.  
  647.         if (TestAbort()) return;
  648.       }
  649.     }
  650.     else if (MoveForward(FH, RelocAmt*4)) return;
  651.   }
  652. }
  653.  
  654. /***********************************************************************/
  655.  
  656. void DoHUNK_DREL32( BPTR FH )
  657. {
  658.   UWORD RelocAmt, RelocHunk, RelocEntry;
  659.   ULONG POF;
  660.  
  661.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_DREL32\n",
  662.     HunkOffset, HunkOrgId );
  663.  
  664.   Cnt_DRel32++;
  665.  
  666.   for(;;)
  667.   {   
  668.     if (MyRead(FH, &RelocAmt, 2)) return;
  669.     if (RelocAmt == NULL) break;        /* End of table? */
  670.     if (MyRead(FH, &RelocHunk, 2)) return;
  671.  
  672.     Cnt_DRel32Ent += RelocAmt;
  673.  
  674.     Printf("\t\t%lu reference%s to hunk #%lu\n",
  675.       (ULONG) RelocAmt,
  676.       Plural(RelocAmt, "", "s"),
  677.       (ULONG) RelocHunk );
  678.  
  679.     stream[1] = RelocHunk;
  680.  
  681.     if (aa[ARG_DREL])
  682.     {
  683.       while (RelocAmt--)
  684.       {
  685.         if (MyRead(FH, &RelocEntry, 2)) return;
  686.  
  687.         Printf("\t\tRelocate offset 0x%04lx using hunk base #%lu\n",
  688.           (ULONG) RelocEntry, (ULONG) RelocHunk );
  689.  
  690.         if (TestAbort()) return;
  691.       }
  692.     }
  693.     else if (MoveForward(FH, RelocAmt*2)) return;
  694.   }
  695.  
  696.   POF = Seek(FH, 0, OFFSET_CURRENT);
  697.  
  698.   /* If we are not on a LONG boundary then align... */
  699.  
  700.   if ((POF >> 2) << 2 != POF)
  701.     if (MoveForward(FH, 2)) return;   /* Alignment fix */
  702.  
  703. }
  704.  
  705. /***********************************************************************/
  706.  
  707. void DoHUNK_RELOC32SHORT( BPTR FH )
  708. {
  709.   UWORD RelocAmt,RelocHunk;
  710.   UWORD RelocEntry;
  711.   ULONG POF;
  712.  
  713.   Cnt_Reloc32Short++;
  714.  
  715.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_RELOC32SHORT\n",
  716.     (ULONG) HunkOffset, (ULONG) HunkOrgId );
  717.  
  718.   for(;;)
  719.   {
  720.     if (MyRead(FH, &RelocAmt, 2)) return;
  721.     if (RelocAmt == NULL) break;        /* End of table? */
  722.     if (MyRead(FH, &RelocHunk, 2)) return;
  723.  
  724.     Cnt_Reloc32SEnt += RelocAmt;
  725.  
  726.     Printf("\t\t%lu reference%s to hunk #%lu\n",
  727.       (ULONG)RelocAmt,
  728.       Plural(RelocAmt, "", "s"),
  729.       (ULONG)RelocHunk );
  730.  
  731.     stream[1] = RelocHunk;
  732.  
  733.     if (aa[ARG_DREL])
  734.     {
  735.       while (RelocAmt--)
  736.       {
  737.         if (MyRead(FH, &RelocEntry, 2)) return;
  738.  
  739.         Printf("\t\tRelocate offset 0x%04lx using hunk base #%lu\n",
  740.           (ULONG) RelocEntry, (ULONG) RelocHunk );
  741.  
  742.         if (TestAbort()) return;
  743.       }
  744.     }
  745.     else if (MoveForward(FH, RelocAmt * 2)) return;
  746.   }
  747.  
  748.   POF = Seek(FH, 0, OFFSET_CURRENT);
  749.  
  750.   /* If we are not on a LONG boundary then align... */
  751.  
  752.   if ((POF >> 2) << 2 != POF)
  753.     if (MoveForward(FH, 2)) return;   /* Alignment fix */
  754. }
  755.  
  756. /***********************************************************************/
  757.  
  758. void DoHUNK_UNIT( BPTR FH )
  759. {
  760.   ULONG NameLen;
  761.   APTR NameBuf;
  762.  
  763.   FFlag_Obj = TRUE;
  764.  
  765.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_UNIT\n",
  766.     HunkOffset, HunkOrgId );
  767.  
  768.   if (MyRead(FH, &NameLen, 4)) return;    /* Get length of name */
  769.  
  770.   if ( NameBuf = (APTR) AllocVec( (NameLen + 1) * 4, MEMF_CLEAR) )
  771.   {
  772.     if (MyRead(FH, NameBuf, NameLen*4)) return;
  773.     Printf("\t\tUnit name: %.40s\n", NameBuf);
  774.     FreeVec(NameBuf);
  775.   }
  776.   else if (MoveForward(FH, NameLen*4)) return;
  777. }
  778.  
  779. /***********************************************************************/
  780.  
  781. void DoHUNK_NAME( BPTR FH )
  782. {
  783.   ULONG NameLen;
  784.   APTR NameBuf;
  785.  
  786.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_NAME\n",
  787.     HunkOffset, HunkOrgId );
  788.  
  789.   if (MyRead(FH, &NameLen, 4)) return;    /* Get length of name */
  790.  
  791.   if (NameBuf = (APTR) AllocVec((NameLen+1)*4, MEMF_CLEAR))
  792.   {
  793.     if (MyRead(FH, NameBuf, NameLen*4)) return;
  794.  
  795.     Printf("\t\tHunk name: %.40s\n", NameBuf);
  796.  
  797.     FreeVec(NameBuf);
  798.   }
  799.   else if (MoveForward(FH, NameLen*4)) return;
  800. }
  801.  
  802. /***********************************************************************/
  803.  
  804. #define EXT_NEWCOMMON 4  /* 5? */
  805.  
  806. void DoHUNK_EXT( BPTR FH )
  807. {
  808.   APTR  ExtTypeStr;
  809.   UBYTE ExtType;
  810.   UWORD ExtLen;
  811.   ULONG ExtOffset;
  812.   ULONG RefCnt;
  813.   ULONG ComSize;
  814.   APTR  ExtSymBuf;
  815.  
  816.   ULONG R1,R2,R3;   /* Results, Used for IO error checking */
  817.  
  818.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_EXT\n",
  819.     HunkOffset, HunkOrgId );
  820.  
  821.   for (;;)
  822.   {
  823.     R1 = MyRead(FH, &ExtType, 1);   /* Read ext type */
  824.     R2 = MoveForward(FH, 1);      /* Alignment fix */
  825.     R3 = MyRead(FH, &ExtLen, 2);    /* Read ext length */
  826.  
  827.     if (R1 || R2 || R3) return;
  828.  
  829.     if (ExtLen == NULL) break;  /* End of ext hunk? */
  830.  
  831.     switch(ExtType)
  832.     {
  833.       case EXT_SYMB: ExtTypeStr = "EXT_SYMB"; goto XDEF;
  834.       case EXT_DEF:  ExtTypeStr = "EXT_DEF";  goto XDEF;
  835.       case EXT_ABS:  ExtTypeStr = "EXT_ABS";  goto XDEF;
  836.       case EXT_RES:  ExtTypeStr = "EXT_RES";
  837.  
  838.         XDEF:   /* sym def, XDEF */
  839.  
  840.         if (ExtSymBuf = (APTR)AllocVec((ExtLen+2)*4, MEMF_CLEAR))
  841.         {
  842.           R1 = MyRead(FH, ExtSymBuf, (ExtLen*4));   /* Read ext symbol */
  843.           R2 = MyRead(FH, &ExtOffset, 4);       /* Read common size */
  844.  
  845.           if (aa[ARG_DEXT])
  846.           {
  847.             Printf("\t\t%-14.14s [%-30.30s] = 0x%08lx\n",         
  848.               (ULONG) ExtTypeStr, (ULONG) ExtSymBuf, ExtOffset );
  849.           }
  850.           FreeVec(ExtSymBuf);
  851.           if (R1 || R2) return;
  852.         }
  853.         else
  854.         {
  855.           R1 = MyRead(FH, &ExtOffset, 4); /* Read common size */
  856.           R2 = MoveForward(FH, ExtLen*4); /* Skip ext symbol */
  857.           if (R1 || R2) return;
  858.         }
  859.         break;
  860.  
  861.       case EXT_COMMON: ExtTypeStr = "EXT_COMMON";
  862.         COMMONREF:  /* common ref */
  863.  
  864.         if (ExtSymBuf = (APTR) AllocVec((ExtLen+2)*4, MEMF_CLEAR))
  865.         {
  866.           R1 = MyRead(FH, ExtSymBuf ,(ExtLen*4)+4);   /* Read ext symbol to buffer */
  867.           R2 = MyRead(FH, &ComSize, 4);         /* Read common size */
  868.           R3 = MyRead(FH, &RefCnt, 4);            /* Read ref count */
  869.           R3 = MoveForward(FH, RefCnt*4);         /* Skip reference entries */
  870.  
  871.           if (aa[ARG_DEXT]) /* Does use want to see ext info? */
  872.           {
  873.             Printf("\t\t%-14.14s [%-30.30s] cs: %lu ref%s: %lu\n",
  874.               (ULONG) ExtTypeStr,
  875.               (ULONG) ExtSymBuf,
  876.               (ULONG) Plural(RefCnt, "", "s"),
  877.               ComSize,
  878.               RefCnt ); /* Check text bounds */
  879.           }
  880.           FreeVec(ExtSymBuf);
  881.           if (R1 || R2 || R3) return;
  882.         }
  883.         else  /* If unable to alloc sym buf then Seek() */
  884.         {
  885.           R1 = MoveForward(FH, (ExtLen*4)+8); /* Skip symbol + common size*/
  886.           R2 = MoveForward(FH, 4);        /* Skip ref count */
  887.           R3 = MoveForward(FH, RefCnt*4);   /* Skip refs */
  888.           if (R1 || R2 || R3) return;
  889.         }
  890.         break;
  891.  
  892.       case EXT_REF32:     ExtTypeStr = "EXT_REF32";     goto XREF;
  893.       case EXT_REF16:     ExtTypeStr = "EXT_REF16";     goto XREF;
  894.       case EXT_REF8:      ExtTypeStr = "EXT_REF8";      goto XREF;
  895.       case EXT_DEXT32:    ExtTypeStr = "EXT_DEXT32";    goto XREF;
  896.       case EXT_DEXT16:    ExtTypeStr = "EXT_DEXT16";    goto XREF;
  897.       case EXT_DEXT8:     ExtTypeStr = "EXT_DEXT8";     goto XREF;
  898.       case EXT_RELREF32:  ExtTypeStr = "EXT_RELREF32";  goto XREF;
  899.       case EXT_RELCOMMON: ExtTypeStr = "EXT_RELCOMMON"; goto XREF;
  900.       case EXT_ABSREF16:  ExtTypeStr = "EXT_ABSREF16";  goto XREF;
  901.       case EXT_ABSREF8:   ExtTypeStr = "EXT_ABSREF8"; 
  902.  
  903.         XREF: /* sym ref, XREF */
  904.  
  905.         if (ExtSymBuf = (APTR) AllocVec((ExtLen*4)+4, MEMF_CLEAR))
  906.         {
  907.           R1 = MyRead(FH, ExtSymBuf, ExtLen*4); /* Read symbol */
  908.           R2 = MyRead(FH, &RefCnt, 4);        /* Read ref count */
  909.           R3 = MoveForward(FH, RefCnt*4);     /* Skip references */
  910.  
  911.           if (aa[ARG_DEXT])
  912.           {
  913.             Printf("\t\t%-14.14s [%-30.30s] ref%s: %lu\n",
  914.               (ULONG) ExtTypeStr,
  915.               (ULONG) ExtSymBuf,
  916.               (ULONG) Plural(RefCnt, "", "s"),
  917.               RefCnt ); /* Check text bounds */
  918.           }
  919.           FreeVec(ExtSymBuf);
  920.           
  921.           if (R1 || R2 || R3) return;
  922.         }
  923.         else
  924.         {
  925.           R1 = MoveForward(FH, ExtLen*4);   /* Skip symbol */
  926.           R2 = MyRead(FH, &RefCnt, 4);      /* Get ref count */
  927.           R3 = MoveForward(FH, RefCnt*4);   /* Skip references */
  928.           if (R1 || R2 || R3) return;
  929.         }
  930.         break;
  931.     }
  932.     if (TestAbort()) break;
  933.   }
  934.  
  935. }
  936.  
  937. /***********************************************************************/
  938.  
  939. void DoUNKNOWN( BPTR FH )
  940. {
  941.   Printf("\tOffset: 0x%08lx - 0x%08lx - Unknown hunk!!!\n",
  942.     HunkOffset, HunkOrgId );
  943.     
  944.   Flag_BadId = TRUE;
  945. }
  946.  
  947. /***********************************************************************/
  948.  
  949. ULONG MoveForward( BPTR FH, LONG Length)
  950. {
  951.   LONG Result = Seek(FH, Length, OFFSET_CURRENT);
  952.  
  953.   if (Result == -1)
  954.   {
  955.     Flag_Error = TRUE;
  956.     return(-1);
  957.   }
  958.   else
  959.     return(NULL);
  960. }
  961.  
  962. /***********************************************************************/
  963.  
  964. BOOL TestAbort( void )
  965. {
  966.   if (CheckSignal(SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  967.   {
  968.     Printf("\n***Break:\n\n");
  969.     Flag_Break = TRUE;
  970.     return(TRUE);
  971.   }
  972.   else
  973.     return(FALSE);
  974. }
  975.  
  976. /***********************************************************************/
  977.  
  978. void BuildFlagString( ULONG Flags, UBYTE *Buf)
  979. {
  980.   /* move.b d0,(a3)+ \n rts */
  981.   
  982.   UWORD putChProc[] = { 0x16c0, 0x4e75 };
  983.  
  984.   stream[0] = (ULONG)"";
  985.   stream[1] = (ULONG)"";
  986.   stream[2] = (ULONG)"";
  987.  
  988.   Flags &= MASK;        /* remove unwanted size */
  989.  
  990.   if (Flags & HUNKF_CHIP)
  991.     stream[0] = (ULONG)"[Load to Chip] ";
  992.   if (Flags & HUNKF_FAST)
  993.     stream[1] = (ULONG)"[Load to Fast] ";
  994.   if (Flags & HUNKF_ADVISORY)
  995.     stream[2] = (ULONG)"[Advisory]";
  996.  
  997.   /* Flush CPU here? */
  998.  
  999.   RawDoFmt("%s%s%s", &stream, (void *) &putChProc, Buf);
  1000. }
  1001.  
  1002. /***********************************************************************/
  1003.  
  1004. LONG MyRead( BPTR FH, APTR Buf, ULONG Length)
  1005. {
  1006.   LONG Result;
  1007.   
  1008.   if (!Length) return 0;  /* If user passes NULL, then return */
  1009.  
  1010.   Result = FRead(FH, Buf, Length, 1);
  1011.  
  1012.   if (Result != 1)
  1013.   {
  1014.     Flag_UEOF = TRUE;
  1015.     return -1;  /* Not OK */
  1016.   }
  1017.   else
  1018.   {
  1019.     return 0;   /* OK */
  1020.   }
  1021. }
  1022.  
  1023. /***********************************************************************/
  1024.  
  1025. UBYTE *Plural( ULONG Val, UBYTE *One, UBYTE *Many)
  1026. {
  1027.   if (Val == 1) return(One); else return(Many);
  1028. }
  1029.  
  1030.  
  1031.  
  1032.